package com.sfh.gd.service.impl;

import cn.dev33.satoken.util.SaResult;
import cn.hutool.core.util.IdUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.sfh.gd.converter.GameConverter;
import com.sfh.gd.converter.GameTeamConverter;
import com.sfh.gd.domain.dto.*;
import com.sfh.gd.domain.dto.web.ChangeMember2DTO;
import com.sfh.gd.domain.dto.web.ChangeMemberDTO;
import com.sfh.gd.domain.entity.*;
import com.sfh.gd.domain.query.GamePageQuery;
import com.sfh.gd.domain.vo.GameScoreSortVO;
import com.sfh.gd.domain.vo.GameTeamAndMemberVO;
import com.sfh.gd.domain.vo.GameVO;
import com.sfh.gd.mapper.*;
import com.sfh.gd.service.GameService;
import com.sfh.gd.service.GameTeamService;
import com.sfh.gd.util.StpKit;
import jodd.util.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.annotation.Transient;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 赛事-队伍
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GameTeamServiceImpl extends ServiceImpl<GameTeamMapper, GameTeamDO> implements GameTeamService {

    /**
     * 报名
     */
    private final GameRegistrationMapper gameRegistrationMapper;
    /**
     * 会员
     */
    private final MemberMapper memberMapper;

    private final GameMapper gameMapper;


    @Override
    public SaResult getGameRank(Long gameId) {
        //赛事排名
        List<GameTeamDO> list = this.getMapper().selectListByQuery(new QueryWrapper().eq(GameTeamDO::getGameId, gameId).orderBy(GameTeamDO::getScoreValue, true));
        //DO 转 VO
        List<GameScoreSortVO> voList = GameConverter.INSTANCE.doToVO(list);
        //取队员名称
        return SaResult.data(voList);
    }

    @Override
    public SaResult signUp(SysGameSignUpDTO data) {
        //赛事报名 平台添加添加选手报名
        GameDO gameDO = this.gameMapper.selectOneById(data.getGameId());
        if (gameDO == null) {
            return SaResult.error("赛事不存在");
        }
        if (gameDO.getStatus() == 3) {
            return SaResult.error("赛事已结束");
        }
        if (gameDO.getStatus() == 4) {
            return SaResult.error("赛事已取消");
        }

        //通过手机号码判断用户是不是存在
        MemberDO userDO = this.findCreateUser(data.getUserPhone());
        if (userDO == null) {
            return SaResult.error("用户创建失败");
        }
        //检查选手1当前赛事是否已经报名
        long count = gameRegistrationMapper.selectCountByQuery(new QueryWrapper().eq(GameRegistrationDO::getGameId, data.getGameId()).eq(GameRegistrationDO::getUserId, userDO.getId()));
        if (count > 0) {
            return SaResult.error(data.getUserPhone() + "已报名");
        }
        if (StringUtil.isNotEmpty(data.getPartnerPhone())) {
            //搭档是否存在
            MemberDO partnerDO = this.findCreateUser(data.getPartnerPhone());
            if (partnerDO == null) {
                return SaResult.error("搭档用户创建失败");
            }
            //检查搭档当前赛事是否已经报名
            count = gameRegistrationMapper.selectCountByQuery(new QueryWrapper().eq(GameRegistrationDO::getGameId, data.getGameId()).eq(GameRegistrationDO::getUserId, partnerDO.getId()));
            if (count > 0) {
                return SaResult.error(data.getPartnerPhone() + "已报名");
            }
            //已有队伍数量
            long teamSize = this.getMapper().selectCountByQuery(new QueryWrapper().eq(GameTeamDO::getGameId, data.getGameId()));
            //创建队伍
            GameTeamDO teamDO = GameTeamDO
                    .builder().
                            gameId(data.getGameId())
                    .code(String.format("%s", teamSize + 1))
                    .teamUser1Id(userDO.getId())
                    .roundCount(0)
                    .scoreValue(gameDO.getScoreValue())
                    .teamUser2Id(partnerDO.getId())
                    .createTime(LocalDateTime.now())
                    .build();
            int insert = this.getMapper().insert(teamDO);
            if (insert <= 0) {
                return SaResult.error("队伍创建失败");
            }
            //添加报名
            List<GameRegistrationDO> list = new ArrayList<>();
            list.add(GameRegistrationDO.builder()
                    .teamId(teamDO.getId())
                    .gameId(data.getGameId())
                    .userId(userDO.getId())
                    .status(data.getIsSignIn() ? 1 : 0)
                    .checkinTime(data.getIsSignIn() ? LocalDateTime.now() : null)
                    .createTime(LocalDateTime.now())
                    .build());

            insert = gameRegistrationMapper.insertBatch(list);
            return SaResult.data(insert > 0);

        } else {
            //添加报名
            int insert = gameRegistrationMapper.insert(GameRegistrationDO.builder()
                    .gameId(data.getGameId())
                    .userId(userDO.getId())
                    .status(data.getIsSignIn() ? 1 : 0)
                    .checkinTime(data.getIsSignIn() ? LocalDateTime.now() : null)
                    .createTime(LocalDateTime.now())
                    .build());
            return SaResult.data(insert > 0);
        }
    }

    @Override
    public SaResult changeTeamMember(ChangeMemberDTO data) {
        //平台更换队伍中换人(新增替换)
        GameTeamDO teamDO = this.getMapper().selectOneByQuery(new QueryWrapper().eq(GameTeamDO::getId, data.getTeamId()));
        if (teamDO == null) {
            return SaResult.error("队伍不存在");
        }
        //查询用户是否存在（已经手机号码）
        MemberDO userDO = this.findCreateUser(data.getUserPhone());
        if (userDO == null) {
            return SaResult.error("用户创建失败");
        }
        if (teamDO.getTeamUser1Id().equals(data.getUserId())) {
            teamDO.setTeamUser1Id(userDO.getId());
        } else if (teamDO.getTeamUser2Id().equals(data.getUserId())) {
            teamDO.setTeamUser2Id(userDO.getId());
        }
        int update = this.getMapper().update(teamDO);
        return SaResult.data(update > 0);
    }

    /**
     * 创建用户
     *
     * @param phoneNum
     * @return
     */
    private MemberDO findCreateUser(String phoneNum) {
        //查询用户是否存在（已经手机号码）
        MemberDO userDO = memberMapper.selectOneByQuery(new QueryWrapper().eq(MemberDO::getPhoneNum, phoneNum));
        if (userDO == null) {
            String code = IdUtil.getSnowflake().nextIdStr();
            userDO = MemberDO.builder()
                    .memberCode(code)
                    .nickName("会员" + code)
                    .phoneNum(phoneNum)
                    .status("0")
                    .remark("系统注册")
                    .createBy(StpKit.ADMIN.getLoginIdAsLong())
                    .updateBy(StpKit.ADMIN.getLoginIdAsLong())
                    .createTime(LocalDateTime.now())
                    .build();
            memberMapper.insert(userDO);
        }
        return userDO;
    }

    @Override
    public SaResult selectChangeTeamMember(ChangeMember2DTO data) {
        //台更换队伍中换人(选择已报名未组队人员替换)
        GameTeamDO teamDO = this.getMapper().selectOneByQuery(new QueryWrapper().eq(GameTeamDO::getId, data.getTeamId()));
        if (teamDO == null) {
            return SaResult.error("队伍不存在");
        }
        // 替换队员
        if (teamDO.getTeamUser1Id().equals(data.getTeamId())) {
            teamDO.setTeamUser1Id(data.getUserId());
        } else if (teamDO.getTeamUser2Id().equals(data.getTeamId())) {
            teamDO.setTeamUser2Id(data.getUserId());
        }
        int update = this.getMapper().update(teamDO);
        return SaResult.data(update > 0);
    }

    @Override
    @Transient
    public SaResult dismissTeam(Long teamId) {
        //解散队伍
        GameTeamDO teamDO = this.getMapper().selectOneByQuery(new QueryWrapper().eq(GameTeamDO::getId, teamId));
        if (teamDO == null) {
            return SaResult.error("队伍不存在");
        }
        int delete = this.getMapper().delete(teamDO);
        if (delete > 0) {
           List<GameRegistrationDO> list = gameRegistrationMapper.selectListByQuery(new QueryWrapper().eq(GameRegistrationDO::getTeamId, teamId));
           if (list != null && list.size() > 0){
               list.forEach(item -> {
                   item.setTeamId( null);//删除队伍ID
                   gameRegistrationMapper.update(item);
               });
           }
        }
        return SaResult.ok();
    }

    @Override
    public SaResult cancelSignUp(SysGameCancelSignUpDTO data) {
        // 平台操作取消报名
        GameRegistrationDO registrationDO = gameRegistrationMapper.selectOneByQuery(new QueryWrapper().eq(GameRegistrationDO::getId, data.getRegistrationId()));
        if (registrationDO == null) {
            return SaResult.error("报名不存在");
        }
        if (registrationDO.getTeamId() > 0){
            //有队伍队伍
            GameTeamDO teamDO = this.getMapper().selectOneByQuery(new QueryWrapper().eq(GameTeamDO::getId, registrationDO.getTeamId()));
            return SaResult.error("该用户已加入队伍【"+teamDO.getCode()+"】,请选解散队伍再取消报名");
        }

        int delete = gameRegistrationMapper.delete(registrationDO);
        return  SaResult.data(delete > 0);
    }

    @Override
    public SaResult getGameAllUserTeam(Long gameId) {
        //获取赛事-所有报名人员列表（已组队，未组队）
        GameTeamAndMemberVO vo = GameTeamAndMemberVO.builder().gameId(gameId).build();

        List<GameTeamDO> teamList = this.getMapper().selectListByQuery(new QueryWrapper().eq(GameTeamDO::getGameId, gameId));
        if (teamList != null && teamList.size() > 0){
            vo.setTeams(  GameTeamConverter.INSTANCE.doToVO(teamList));
        }
        //获取赛事-所有报名人员列表（未组队）teamId=null
        List<GameRegistrationDO> list = gameRegistrationMapper.selectListByQuery(new QueryWrapper().eq(GameRegistrationDO::getGameId, gameId)
                .eq(GameRegistrationDO::getTeamId, null));
        if (list != null && list.size() > 0){
            vo.setMembers(GameTeamConverter.INSTANCE.doToRegistrationVO(list));
        }
        return SaResult.data(vo);
    }
}